﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using JXT.PrimaryKey.Batman.Domain.Models;
using JXT.PrimaryKey.Batman.Domain.Specifications.Expressions;

namespace JXT.PrimaryKey.Batman.Domain.Specifications.Expressions
{
    public class ExpressionSpecification<TEntity> : ISpecification<TEntity> where TEntity : IEntity
    {
        private Expression<Func<TEntity, bool>> _whereExpression;

        public Expression<Func<TEntity, bool>> WhereExpression
        {
            get
            {
                if (_whereExpression == null)
                    return e => true;
                return _whereExpression;
            }
        }

        public void And(Expression<Func<TEntity, bool>> predicate)
        {
            if (_whereExpression == null)
            {
                _whereExpression = predicate;
            }
            else
            {
                QueryExpressionVisitor<TEntity> visitor = new QueryExpressionVisitor<TEntity>(predicate);
                _whereExpression = visitor.Convert(_whereExpression, _whereExpression.Parameters[0], WhereType.And);
            }
        }

        public void Or(Expression<Func<TEntity, bool>> predicate)
        {
            if (_whereExpression == null)
            {
                _whereExpression = predicate;
            }
            else
            {
                QueryExpressionVisitor<TEntity> visitor = new QueryExpressionVisitor<TEntity>(predicate);
                _whereExpression = visitor.Convert(_whereExpression, _whereExpression.Parameters[0], WhereType.Or);
            }
        }
    }
}
